package com.lepu.app.fun.tool.jqtx.util;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.json.JSONObject;

import android.content.Context;
import android.text.TextUtils;

import com.app.application.MyApplication;
import com.app.config.UserConfig;
import com.app.utils.Const;
import com.app.utils.DateUtil;
import com.app.utils.LoginUtil;
import com.app.utils.Setting;
import com.core.lib.core.ApiClient;
import com.core.lib.core.AsyncRequest;
import com.core.lib.utils.main.DateUtilBase;
import com.core.lib.utils.main.LogUtilBase;
import com.core.lib.utils.main.UtilityBase;
import com.eyzhs.app.R;
import com.lepu.app.fun.grow.calendar.GrowSpecialCalendar;
import com.lepu.app.fun.tool.jqtx.bean.BeanJqtx;
import com.lepu.app.fun.tool.jqtx.remind.Alarm;

public class ToolJqtxUtil implements AsyncRequest {

	private static final String REQUEST_JQTX_DATA = "request_jqtx_data";

	private static ToolJqtxUtil mInstance = null;
	private static Context mContext = null;

	private ToolJqtxUtil() {

	}

	public static ToolJqtxUtil getInstance(Context c) {
		if (mInstance == null) {
			mContext = c;
			mInstance = new ToolJqtxUtil();
		}
		return mInstance;
	}

	// ==============================================
	public void requestJqtxData() {

		Map<String, Object> map = new HashMap<String, Object>();
		JSONObject params = new JSONObject();
		try {
			params.put("DeviceID", Setting.DEVICEID);
			params.put("ApplicationID", Setting.APPLICATIONID);
			params.put("UserID", LoginUtil.getUserId());
			params.put("LoginToken", LoginUtil.getLoginToken());
		} catch (Exception e) {
		}
		map.put("ht", params);

		ApiClient.http_post_main(Setting.getUserMenstruation(), map, null,
				this, REQUEST_JQTX_DATA, false);
	}

	public boolean checkIfSetJqtx() {
		boolean flag = false;

		if (getJqtx() != null) {
			flag = true;
		}
		return flag;
	}

	public boolean checkRemindIfOpen() {
		boolean flag = false;

		BeanJqtx item = getJqtx();
		if (item != null) {
			if(item.IsAlert == 1)
			{
				flag = true;
			}
		}
		return flag;
	}

	public BeanJqtx getJqtx() {

		BeanJqtx item = null;
		String data = UserConfig.getConfigString(mContext,
				Const.CONFIG_APP_TOOL_JQTX_DATA, "");
		if (!TextUtils.isEmpty(data)) {
			item = BeanJqtx.parseBean(data);
		}
		return item;
	}

	public void updateJqtx(String data) {
		if (!TextUtils.isEmpty(data)) {
			UserConfig.setConfig(mContext, Const.CONFIG_APP_TOOL_JQTX_DATA,
					data);
			setJqtxRemind(false, 0);
		}
	}

	/**
	 * 设置经期提醒闹钟
	 */
	public void setJqtxRemind(boolean cycleAdd, int typeAdd) {
		BeanJqtx item = getJqtx();
		if (item != null) {

			if (item.IsAlert == 1) {
				int jqDay = item.MenstrualPeriod;// 经期
				int zqDay = item.MenstrualCycle;// 周期
				Date beginDate = DateUtilBase.dateFromString(
						item.LastMenstruationDate, DateUtilBase.YEAR_MONTH_DAY);
				int beforeDay = item.AlertBeforeDay;
				String alertTime = item.AlertTime;// 00:00:00

				Date currentDate = DateUtilBase.dateFromString(
						DateUtilBase.stringFromDate(new Date(),
								DateUtilBase.YEAR_MONTH_DAY),
						DateUtilBase.YEAR_MONTH_DAY);

				if (!TextUtils.isEmpty(item.AlertType)) {
					String[] alertTypeArray = item.AlertType.split("\\|");
					if (alertTypeArray.length > 0) {
						
						ArrayList<Date> aqqDateList = new ArrayList<Date>();
						for (int i = 0; i < alertTypeArray.length; i++) {
							Date remindDate = null;
							String note = "";
							int type = UtilityBase.parseInt(alertTypeArray[i]);
							
							if(type <= 0)
							{
								continue;
							}
							
							if (type == 1) {
								note = mContext.getResources().getString(
										R.string.jqtx_remind_tip_yjq);

								// 月经期 加周期就行包含了经期
								remindDate = getYjqDate(currentDate, beginDate,
										zqDay);

								if (Setting.DEBUG) {
									String dateString = DateUtilBase
											.stringFromDate(remindDate,
													DateUtilBase.YEAR_MONTH_DAY);
									LogUtilBase
											.LogD(null, String.format("月经期：%s",
													dateString));
								}

								// 月经期截至日期
								// Date yjEndDate =
								// DateUtilBase.addDateOfDay(yjBeginDate,
								// jqDay);
							} else if (type == 2) {
								// 安全期
								note = mContext.getResources().getString(
										R.string.jqtx_remind_tip_aqq);

								aqqDateList = getAqqDate(currentDate, beginDate,
										jqDay,zqDay);

								if (Setting.DEBUG) {
									String dateString = DateUtilBase
											.stringFromDate(aqqDateList.get(0),
													DateUtilBase.YEAR_MONTH_DAY);
									LogUtilBase
											.LogD(null, String.format("安全期 0：%s",
													dateString));
								}

							} else if (type == 3) {
								// 易孕期=起始日期：排卵日减5，截止日期：排卵日加4
								note = mContext.getResources().getString(
										R.string.jqtx_remind_tip_yyq);

								Date plqDate = getPlqDate(currentDate,
										beginDate, zqDay);
								remindDate = DateUtilBase.addDateOfDay(plqDate,
										-5);

								if (Setting.DEBUG) {
									String dateString = DateUtilBase
											.stringFromDate(remindDate,
													DateUtilBase.YEAR_MONTH_DAY);
									LogUtilBase
											.LogD(null, String.format("易孕期：%s",
													dateString));
								}

								// 截至日期
								// Date yyqEndDate =
								// DateUtilBase.addDateOfDay(plqDate,
								// 4);

							} else if (type == 4) {
								// 排卵日=上次月经期日期+周期-14 只有1天，没有截至日期
								note = mContext.getResources().getString(
										R.string.jqtx_remind_tip_plq);

								remindDate = getPlqDate(currentDate, beginDate,
										zqDay);

								if (Setting.DEBUG) {
									String dateString = DateUtilBase
											.stringFromDate(remindDate,
													DateUtilBase.YEAR_MONTH_DAY);
									LogUtilBase
											.LogD(null, String.format("排卵日：%s",
													dateString));
								}
							}

							if (remindDate != null || aqqDateList.size() > 0) {

								// 记录每一次设置的提醒时间戳
								String key = "";
								int cycleIndex = 1;
								if (type == 1) {
									key = Const.CONFIG_APP_TOOL_JQTX_REMIND_YJQ;
								}else if (type == 2) {
									cycleIndex = 0;
								} else if (type == 3) {
									key = Const.CONFIG_APP_TOOL_JQTX_REMIND_YYQ;
								} else if (type == 4) {
									key = Const.CONFIG_APP_TOOL_JQTX_REMIND_PLQ;
								}

								for(int j=cycleIndex;j<2;j++)
								{
									long alarmTime = 0;
									if(cycleIndex == 0)
									{
										//安全期提醒
										if(j == 0)
										{
											key = Const.CONFIG_APP_TOOL_JQTX_REMIND_AQQ_1;
											alarmTime = aqqDateList.get(0).getTime();
										}else{
											key = Const.CONFIG_APP_TOOL_JQTX_REMIND_AQQ_2;
											alarmTime = aqqDateList.get(1).getTime();
										}
									}else{
										alarmTime = remindDate.getTime();
									}
									
									if (cycleAdd && (typeAdd == type || typeAdd == 20) ) {
										long preAlarmTime = UserConfig
												.getConfigLong(mContext, key, 0);
										if (preAlarmTime > 0) {
											long addTime = zqDay*DateUtil.DAY_MILLIS;
											alarmTime = (preAlarmTime + addTime);
										}
									}

									UserConfig.setConfig(mContext, key, alarmTime);

									if (beforeDay > 0) {
										long addTime = beforeDay*DateUtil.DAY_MILLIS;
										alarmTime -= addTime;
									}

									String dateString = DateUtilBase.stringFromDate(new Date(alarmTime),DateUtilBase.YEAR_MONTH_DAY);
									dateString = dateString+" "+alertTime;
									Date date = DateUtilBase.dateFromString(dateString,DateUtilBase.DATE_ALL_ALL);

									alarmTime = date.getTime();

									if (alarmTime < DateUtil.getNowTimeInMillis()) {
										
										long addTime = zqDay*DateUtil.DAY_MILLIS;
										long time = alarmTime + addTime;
										alarmTime = time;
									}

									if (Setting.DEBUG) {
										String tempString = DateUtilBase
												.stringFromDate(new Date(alarmTime),
														DateUtilBase.DATE_ALL_ALL);
										LogUtilBase
												.LogD(null, String.format("期类型：%d，最终提醒时间：%s",
														type,tempString));
									}

									Alarm alarm = new Alarm();
									alarm.alarmId = type;
									alarm.uid = LoginUtil.getUserId();
									alarm.alarmTime = alarmTime;
									alarm.setTime = DateUtil.getNowTimeInMillis();
									alarm.note = note;
									
									if(cycleIndex == 0)
									{
										//安全期
										if(j == 0)
										{
											alarm.type = type;//2
										}else{
											alarm.type = 20;//20
										}
									}else{
										alarm.type = type;
									}

									//先关闭这个type的闹钟，再重新设置闹钟
									Alarm.closeRemind(MyApplication.alarmManager, mContext, type);
									Alarm.setRemindNoDB(alarm,
											MyApplication.alarmManager, mContext);
								}
							}
						}
					}
				}
				// ==========================
			} else {
				// close remind
				// 不关闭闹钟了，如果提醒关闭，闹钟响了，会先监测提醒是否打开。否则即使闹钟时间到了，代码不让执行通知。
				//所以不关闭闹钟，也没事儿
				Alarm.closeRemind(MyApplication.alarmManager, mContext, 1);
				Alarm.closeRemind(MyApplication.alarmManager, mContext, 2);//安全提醒的第一个闹钟
				Alarm.closeRemind(MyApplication.alarmManager, mContext,3);
				Alarm.closeRemind(MyApplication.alarmManager, mContext, 4);
				Alarm.closeRemind(MyApplication.alarmManager, mContext, 20);//安全提醒的第二个闹钟
			}
		}
	}
	
	public void setJqtxRemindAlarm(boolean cycleAdd, int typeAdd) {
		
	}

	/**
	 * // 月经期 加周期就行包含了经期
	 * 
	 * @param beginDate
	 * @param zqDay
	 * @return
	 */
	public static Date getYjqDate(Date currentDate, Date beginDate, int zqDay) {

		long days = (currentDate.getTime() - beginDate.getTime())
				/ (24 * 60 * 60 * 1000);
		int cycle = (int) (days / zqDay);// 几个周期

		int addDays = cycle * zqDay;
		Date yjBeginDate = DateUtilBase.addDateOfDay(beginDate, addDays);

		// 获取当前月第一天：
		// Calendar cFirst = Calendar.getInstance();
		// cFirst.add(Calendar.MONTH, 0);
		// cFirst.setTime(currentDate);
		// cFirst.set(Calendar.DAY_OF_MONTH, 1);// 设置为1号,当前日期既为本月第一天

		String dateString = DateUtilBase.stringFromDate(currentDate, "yyyy-MM");
		String dateStringNew = dateString + "-01";
		Date firstDate = DateUtilBase.dateFromString(dateStringNew,
				DateUtilBase.YEAR_MONTH_DAY);

		// 获取当前月最后一天
		// Calendar cEnd = Calendar.getInstance();
		// cEnd.set(Calendar.DAY_OF_MONTH,
		// cEnd.getActualMaximum(Calendar.DAY_OF_MONTH));

		if (yjBeginDate.getTime() < firstDate.getTime()) {
			yjBeginDate = DateUtilBase.addDateOfDay(yjBeginDate, zqDay);
		}
		// else{
		// yjBeginDate = DateUtilBase.addDateOfDay(yjBeginDate, -zqDay);
		// }

		return yjBeginDate;
	}

	/**
	 * 安全期 月经期的截至日期+1 就是安全期
	 * 安全期 排卵日的截至日期+1 就是安全期
	 * 
	 * @param beginDate
	 * @param zqDay
	 * @return
	 */
	public static ArrayList<Date> getAqqDate(Date currentDate, Date beginDate, int jqDay,int zqDay) {

		ArrayList<Date> dateList = new ArrayList<Date>();
		
		Date yjqDate = getYjqDate(currentDate, beginDate, zqDay);
		Date aqqBeginDate1 = DateUtilBase.addDateOfDay(yjqDate, jqDay + 1);
		
		Date plqDate = getPlqDate(currentDate, beginDate, zqDay);
		Date aqqBeginDate2 = DateUtilBase.addDateOfDay(plqDate, 4 + 1);
		
		dateList.add(aqqBeginDate1);
		dateList.add(aqqBeginDate2);
		
		return dateList;
	}

	/**
	 * // 排卵日=上次月经期日期+周期-14 只有1天，没有截至日期
	 * 
	 * @param beginDate
	 * @param zqDay
	 * @return
	 */
	public static Date getPlqDate(Date currentDate, Date beginDate, int zqDay) {
		Date plqDate = DateUtilBase.addDateOfDay(
				getYjqDate(currentDate, beginDate, zqDay), zqDay - 14);
		return plqDate;
	}

	//============================================================================
	// ===========================================================================
	
	/**
	 * // 月经期 加周期就行包含了经期
	 * 
	 * @param beginDate
	 * @param zqDay
	 * @return
	 */
	public static Date getYjqDateListFlag(Date currentDate, Date beginDate, int zqDay) {

		Date yjqBeginDate = null;
		long days = (currentDate.getTime() - beginDate.getTime())
				/ (24 * 60 * 60 * 1000);
		int cycle = (int) (days / zqDay);// 几个周期

		if(cycle > 0)
		{
			int addDays = cycle * zqDay;
			yjqBeginDate = DateUtilBase.addDateOfDay(beginDate, addDays);
		}else{
			yjqBeginDate = beginDate;
		}

		//test
//		String dateString = DateUtilBase.stringFromDate(currentDate, "yyyy-MM");
//		String dateStringNew = dateString + "-01";
//		Date firstDate = DateUtilBase.dateFromString(dateStringNew,
//				DateUtilBase.YEAR_MONTH_DAY);
//
//		if (beginDate.getTime() < firstDate.getTime()) {
//			beginDate = DateUtilBase.addDateOfDay(beginDate, zqDay);
//		}

		return yjqBeginDate;
	}
	
	/**
	 * // 排卵日=上次月经期日期+周期-14 只有1天，没有截至日期
	 * 
	 * @param beginDate
	 * @param zqDay
	 * @return
	 */
	public static Date getPlqDateList(Date currentDate, Date beginDate, int zqDay) {
		Date plqDate = DateUtilBase.addDateOfDay(
				getYjqDateListFlag(currentDate, beginDate, zqDay), zqDay - 14);
		return plqDate;
	}

	
	/**
	 * 获取月经期时间数组
	 * 
	 * @param context
	 * @param jumpMonth
	 * @param jumpYear
	 * @return
	 */
	public static ArrayList<String> getYjqList(Context context, int jumpMonth,
			int jumpYear) {
		ArrayList<String> dataList = new ArrayList<String>();

		BeanJqtx item = ToolJqtxUtil.getInstance(context).getJqtx();
		if (item != null) {
			int jqDay = item.MenstrualPeriod;// 经期
			int zqDay = item.MenstrualCycle;// 周期
			Date beginDate = DateUtilBase.dateFromString(
					item.LastMenstruationDate, DateUtilBase.YEAR_MONTH_DAY);
			
			// 获取当前月第一天：
			GrowSpecialCalendar sc = new GrowSpecialCalendar();
			boolean isLeapyear = sc.isLeapYear(jumpYear); // 是否为闰年
			int daysOfMonth = sc.getDaysOfMonth(isLeapyear, jumpMonth); // 某月的总天数

			for (int i = 1; i <= daysOfMonth; i++) {
				String dateStr = jumpYear + "-" + jumpMonth + "-" + i;
				Date currentDate = DateUtilBase.dateFromString(dateStr,
						"yyyy-M-d");

				Date beginYjqDate = getYjqDateListFlag(currentDate, beginDate, zqDay);
				Date endYjqDate = DateUtilBase
						.addDateOfDay(beginYjqDate, jqDay);
				if (currentDate.getTime() >= beginYjqDate.getTime()
						&& currentDate.getTime() < endYjqDate.getTime()) {
					dataList.add(DateUtilBase.stringFromDate(currentDate,
							DateUtilBase.YEAR_MONTH_DAY));
				}
			}
		}

		return dataList;
	}

	/**
	 * 获取易孕期时间数组
	 * 
	 * @return
	 */
	public static ArrayList<String> getYyqList(Context context, int jumpMonth,
			int jumpYear) {
		ArrayList<String> dataList = new ArrayList<String>();

		BeanJqtx item = ToolJqtxUtil.getInstance(context).getJqtx();
		if (item != null) {
			// int jqDay = item.MenstrualPeriod;// 经期
			int zqDay = item.MenstrualCycle;// 周期
			Date beginDate = DateUtilBase.dateFromString(
					item.LastMenstruationDate, DateUtilBase.YEAR_MONTH_DAY);

			// 获取当前月第一天：
			GrowSpecialCalendar sc = new GrowSpecialCalendar();
			boolean isLeapyear = sc.isLeapYear(jumpYear); // 是否为闰年
			int daysOfMonth = sc.getDaysOfMonth(isLeapyear, jumpMonth); // 某月的总天数

			for (int i = 1; i <= daysOfMonth; i++) {
				String dateStr = jumpYear + "-" + jumpMonth + "-" + i;
				Date currentDate = DateUtilBase.dateFromString(dateStr,
						"yyyy-M-d");

				Date plqDate = getPlqDateList(currentDate, beginDate, zqDay);
				Date beginYyqDate = DateUtilBase.addDateOfDay(plqDate, -5);
				Date endYyqDate = DateUtilBase.addDateOfDay(plqDate, 4);

				if (currentDate.getTime() >= beginYyqDate.getTime()
						&& currentDate.getTime() <= endYyqDate.getTime()) {
					dataList.add(DateUtilBase.stringFromDate(currentDate,
							DateUtilBase.YEAR_MONTH_DAY));
				}
			}
		}

		return dataList;
	}

	/**
	 * 获取排卵期时间数组
	 * 
	 * @return
	 */
	public static ArrayList<String> getPlqList(Context context, int jumpMonth,
			int jumpYear) {
		ArrayList<String> dataList = new ArrayList<String>();

		BeanJqtx item = ToolJqtxUtil.getInstance(context).getJqtx();
		if (item != null) {
			// int jqDay = item.MenstrualPeriod;// 经期
			int zqDay = item.MenstrualCycle;// 周期
			Date beginDate = DateUtilBase.dateFromString(
					item.LastMenstruationDate, DateUtilBase.YEAR_MONTH_DAY);

			// 获取当前月第一天：
			GrowSpecialCalendar sc = new GrowSpecialCalendar();
			boolean isLeapyear = sc.isLeapYear(jumpYear); // 是否为闰年
			int daysOfMonth = sc.getDaysOfMonth(isLeapyear, jumpMonth); // 某月的总天数

			for (int i = 1; i <= daysOfMonth; i++) {
				String dateStr = jumpYear + "-" + jumpMonth + "-" + i;
				Date currentDate = DateUtilBase.dateFromString(dateStr,
						"yyyy-M-d");

				Date plqDate = getPlqDateList(currentDate, beginDate, zqDay);

				if (currentDate.getTime() == plqDate.getTime()) {
					dataList.add(DateUtilBase.stringFromDate(currentDate,
							DateUtilBase.YEAR_MONTH_DAY));
				}
			}
		}

		return dataList;
	}

	// ==============================================
	@Override
	public void RequestComplete(Object object, Object data) {
		if (object.equals(REQUEST_JQTX_DATA)) {
			LogUtilBase.LogD(null, "REQUEST_JQTX_DATA success");

			String beanString = BeanJqtx.parseBeanString((String) data);
			updateJqtx(beanString);
		}
	}

	@Override
	public void RequestError(Object object, int errorId, String data) {
		if (object.equals(REQUEST_JQTX_DATA)) {
			LogUtilBase.LogD(null, "REQUEST_JQTX_DATA fail");
			setJqtxRemind(false, 0);
		}
	}
}
